package systems.ik 
{

    import flash.display.Sprite;
    import flash.events.Event;

    [SWF (width = "465", height = "465", frameRate = "30", backgroundColor = "0x333333")]

    public class Chain extends Sprite {
        
        private const RADIUS:uint = 5;
        private const LINK_LENGTH:uint = 40;
        private const JOINT_COUNT:uint = 10;
        private const DELAY:Number = 0.95;
        private var jointList:Array = [];
        
        public function Chain ():void {
            var i:int;
            for (i = 0; i < JOINT_COUNT; i++) {
                jointList [i] = makeJoint (RADIUS);
                jointList [i].x = Math.random () * stage.stageWidth;
                jointList [i].y = Math.random () * stage.stageHeight;
                addChild (jointList [i]);
            }
            addEventListener (Event.ENTER_FRAME, loop);
        }
        
        private function loop (event:Event):void {
            jointList [0].x = mouseX;
            jointList [0].y = mouseY;
            graphics.clear ();
            graphics.lineStyle (0, 0xFFFFFF, 0.5);
            graphics.moveTo (jointList [0].x, jointList [0].y);
            var i:int;
            for (i = 0; i < JOINT_COUNT - 1; i++) {
                chaseJoint (jointList [i], jointList [i + 1]);
                graphics.lineTo (jointList [i + 1].x, jointList [i + 1].y);
            }
        }
        
        private function chaseJoint (joint1:Sprite, joint2:Sprite):void {
            var dx:Number = joint1.x - joint2.x;
            var dy:Number = joint1.y - joint2.y;
            var d:Number = Math.sqrt (dx * dx + dy * dy);
            var rate:Number = (d - LINK_LENGTH) / d * DELAY;
            rate = (Math.abs (rate) < 0.01) ? 0 : rate;
            joint2.x += dx * rate;
            joint2.y += dy * rate;
        }
        
        private function makeJoint (radius:Number):Sprite {
            var joint:Sprite = new Sprite ();
            joint.graphics.beginFill (0xFFFFFF, 0.5);
            joint.graphics.drawCircle (0, 0, radius);
            joint.graphics.endFill ();
            return joint;
        }
        
    }
    
}